\documentclass[11pt]{article}

\usepackage[utf8]{inputenc}
\usepackage[frenchb]{babel}
\usepackage{a4}
\usepackage{graphicx}
\usepackage{verbatim}


\begin{document}

\title{Rapport de projet de POO}
\author{Rémi DESTIGNY, Isaline LAURENT, Christiane MELI}
\maketitle
\section*{Introduction}
Ce projet a pour but le développement d’une solution de journalisation du framework java développé en séance de TD. Ce framework permet la gestion de transports en commun et de leur usagers. Pour en améliorer la qualité, il est nécessaire de journaliser une partie du code, à savoir la partie gérant les Transports. 

\section{Présentation générale du projet}

Le framework tec que nous souhaitons journaliser a été développé par nos soins. Il comporte deux classes importantes : Autobus et Passager qui contiennent la majorité de la logique du programme. Le but est de simuler le trajet de passagers aux comportements et humeurs différents dans des bus disposant d’un nombre limité de place assises et debout. Ces deux classes sont épaulées par une suite de tests unitaires accessible à l’execution depuis un autre package appelé Poounit. Un mécanisme de levée et de remontée d’exceptions a également été mis en place afin d’assurer le bon fonctionnement du code et un traitement adéquat en cas d’erreur. 

Le diagramme de classe simplifié du framework est visible en Annexe \ref{diag_classe}.

L’objectif principal mis en avant lors du développement était d’obtenir un code réutilisable, modulable et évitant au maximum les duplications de code. Une autre contrainte dans l’implémentation était la visibilité des classes du framework. En effet le client a besoin d’un framework n’exposant que la partie nécessaire à son travail. Ces méthodes sont contenues dans les interfaces Usager et Transport qui servent d’interface entre le code du client et le notre. Vient ensuite une interface pour les Bus et pour les passagers afin de faciliter l’ajout de nouveaux types de passagers ou de Bus. La hiérarchie s’arrête ici pour les Autobus qui héritent donc des interfaces Transport et Bus et implémentent toutes les méthodes héritées. Les passagers de leur coté nécessitaientt plus de spécialisation afin de gérer leurs humeurs et leur comportements. L’héritage multiple n’existant pas en Java, nous avons du utiliser deux méthodes différentes pour gérer d’un coté les comportements et de l’autre les humeurs. Les différentes humeurs sont des classes filles de PassagerAbstrait qui déterminent l’attitude du passager à la montée dans le bus en redéfinissant la méthode choixPlaceMontee(). 

Les comportements sont gérés via un lien “à-un”, chacun possédant une méthode s’appliquant sur un Passager. Le comportement est choisi par le client à la construction de l’objet. Cette méthode permet d’ajouter facilement un nouveau comportement ou une nouvelle humeur. La seule modification à faire se trouve au niveau du switch qui instancie le comportement contenu dans le passager. 

Après cette brève présentation du framework nous allons nous attarder sur le problème de la journalisation et la solution que nous allons lui apporter. 

\section{Journalisation du Framework}


Pour la journalisation nous avons opté pour une solution alliant un lien “est-un” et un lien “a-un”. L’idée est d’avoir une classe JournalAutobus qui contient un Journal. Ce journal est une interface pour les services de journalisation fournissant les méthodes à implémenter. Les méthodes de JournalAutobus ne font que redéfinir les méthodes d’un Autobus de la manière suivante :

\begin{verbatim}
@override
methode(parametre)
{
    super.methode(parametre);
    journal.loggerMethode();
}
\end{verbatim}

Les différents services de journalisation héritent ensuite de Journal et fournissent les fonctions de log sur la sortie d’erreur ou encore dans un fichier. Le schéma correspondant est visible en Annexe \ref{diag_sol}.

Cette solution est très avantageuse pour plusieurs raisons : 
\begin{itemize}
\item[•]Forte résistance aux modifications : En effet si l’on souhaite ajouter une classe Tramway par exemple, seul l’équivalent de la classe AutobusJournal doit être recodé ce qui permet l’ajout rapide de nouveaux moyens de transports ( La classe AutobusJournal est de plus triviale à écrire ). Si d’un autre coté on souhaite ajouter un nouveau service de journalisation comme JournalDataBase, il suffit d’hériter de l’interface Journal et d’implémenter les méthodes qu’elle contient pour créer ce service. 
\item[•]Duplication faible du code : Le code recopié est réduit au strict minimum. On aurait même pu pousser jusqu’a faire une classe mère pour JournalErreur et JournalNormal prenant un flux de sortie en entrée et renvoyant sur le bon flux en fonction de la classe instanciée. Cependant ce refactoring n’était pas nécessaire et n’apportait pas un grand intérêt.  
\item[•]La création d’objet est peut être la partie la moins simple. En effet l’utilisateur doit lui même instancier le service de journalisation qu’il souhaite utiliser et le passer en paramètre lors de la construction de l’autobus journalisé. Une piste d’amélioration serait éventuellement d’utiliser une énumération pour gérer l’instanciation du service mais cela nous obligerait à modifier la classe AutobusJournal et ses éventuels équivalents à chaque nouveau service de journalisation. L’utilisateur peut néanmoins choisir de ne pas utiliser de journalisation du tout en instanciant simplement un Autobus. 
\end{itemize}

\section{Log4J - SLF4J}

Nous avons présenté notre solution basique de loging. L’idée est maintenant de découvrir les solutions existantes actuellement dans le monde Java. Notre étude se portera sur Log4J et SLF4J qui sont deux frameworks de loging disponibles ici : http://logging.apache.org/log4j/ et http://slf4j.org/. 

Ces deux frameworks se ressemble beaucoup au niveau de l’utilisation mais log4j propose des fonctionnalités plus avancées. L’implémentation basique est proche de notre version, on utilise un lien “a-un” entre l’entité de service de journalisation et la classe à journaliser. 

Avec log4j il suffit de créer un logger ( ceux ci peuvent être organisés de manière hiérarchique d’une manière similaire aux package Java afin de sélectionner quelle branche ou sous branche doit être journalisée), on peut ensuite définir son niveau de Log : Trace, Debug, Info, Warn, Error, Fatal ( donnés par ordre croissant d’importance ). On peut ensuite utiliser ce logger pour journaliser des informations d’importances supérieures ou égales au niveau défini. Log4J propose ensuite des “appenders” permettant de gérer le canal de sortie des logs et des “Layouts” gérant le formatage de l’information.

Slf4j adopte une idée similaire mais épurée. On crée également un objet Logger qui dispose de méthode correspondant aux niveaux de logs qui sont les mêmes que log4j à l’exception de niveau “Fatal”. Ce niveau de log n’existe pas car l’équipe de slf4j considère qu’utiliser ce niveau outrepasse la tache d’un logger qui n’est pas de gérer des erreurs entraînant la fermeture du programme. 

L’avantage de ces deux solutions par rapport à la notre est clairement le niveau de log qui offre la possibilité de classer les informations et permet un debug efficace de l’application. L’apport de log4j au niveau de la hiérarchisation des logs permet de catégoriser encore plus les logs en séparant par exemple les logs d’un package, voire même d’une classe en particulier. Ce genre de fonctionalité est très appréciée lorsqu’un debugger n’est pas disponible, comme par exemple dans des applications distribués. Cette méthode permet également de garder une trace du debug là où l’utilisation d’un debugger est éphémère, l’utilisation du logger permet de revenir sur d’ancien debug facilitant et accélérant la correction d’erreurs.

\section*{Conclusion}

	En guise de conclusion, nous aborderons le danger d’une journalisation trop intensive qui risque de nuire à la vitesse d'exécution du programme en environnement de production. C’est justement l’avantage de notre solution, en changeant simplement la ligne de compilation on peut choisir d’utiliser les logs ou non via une seule clause if, par instanciation là où les loggers présentés sont obligés de tester à chaque log. Cette solution n’est cependant pas viable dans un gros projet puisqu’il impliquerait de quasiment doubler le nombre de classes présentes de celui ci. 
	
\newpage
\section*{Annexe}
\begin{figure}[h!]

\includegraphics[scale=0.5]{general.png}
\caption{Diagramme de classe général de l'application}
\label{diag_classe}
\end{figure}

\begin{figure}[h!]
\caption{Diagramme de classe de la partie journalisation}
\includegraphics[scale=0.5]{Journal.png}
\label{diag_sol}
\end{figure}

\end{document}
